package com.it.data_array.dynamic_array;

import com.it.data_tree.util.ColorPrintln;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.Stream;

/**
 * @Author: Coke
 * @DateTime: 2023/05/07/21:33
 * @注释: TODO
 **/
public class DynamicArray<T> implements Iterable<T> {
    private int size = 0; // 逻辑大小
    private int capacity = 8; // 容量
    private Object[] array = {};
    
    /**
     * @param element: 需要插入的值
     * @return void
     * @作者: Coke
     * @注释: 向最后位置插入元素
     * @DateTime: 2023/5/13 13:51
     */
    public void add (T element) {
        extracted();
        array[size] = element;
        size++;
    }
    
    /**
     * @return void
     * @作者: Coke
     * @注释: 扩容方法
     * @DateTime: 2023/5/13 19:09
     */
    private void extracted () {
        if (size == 0) {
            array = new Object[capacity];
        } else if (size > size / 4 * 3) {
            Object[] newArray = new Object[capacity += capacity >>> 1];
            System.arraycopy(array, 0, newArray, 0, size);
            array = newArray;
        }
    }
    
    /**
     * @param index:   指定位置
     * @param element: 插入的元素
     * @return void
     * @作者: Coke
     * @注释: 向指定位置插入元素
     * @DateTime: 2023/5/13 14:02
     */
    public void add (int index, T element) {
        extracted();
        if (index >= 0 && index < size) {
            // 形参:src – 源数组。 srcPos – 源数组中的起始位置。 dest – 目标数组。 destPos – 目标数据中的起始位置。 length – 要复制的数组元素的数量
            System.arraycopy(array, index, array, index + 1, size - index);
            array[index] = element;
            size++;
        } else if (index == size) {
            add(element);
        }
    }
    
    /**
     * @return void
     * @作者: Coke
     * @注释: 遍历打印数组
     * @DateTime: 2023/5/13 14:24
     */
    public void print () {
        StringBuffer buffer = new StringBuffer();
        buffer.append("[");
        for (int i = 0; i < size; i++) {
            if (i == 0) {
                buffer.append(array[i]);
            } else {
                buffer.append(", ").append(array[i]);
            }
        }
        buffer.append("]");
        ColorPrintln.greenPrintln(buffer);
    }
    
    /**
     * @param consumer:
     * @return void
     * @作者: Coke
     * @注释: 遍历数据（传入函数式接口 自定义处理过程）
     * @DateTime: 2023/5/13 14:37
     */
    public void print (Consumer<T> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept((T) array[i]);
        }
    }
    
    /**
     * @param index:
     * @return T
     * @作者: Coke
     * @注释: 根据索引获取元素
     * @DateTime: 2023/5/13 14:28
     */
    public T get (int index) {
        if (index >= 0 && index < size) {
            return (T) array[index];
        }
        return null;
    }
    
    /**
     * @return Iterator<T>
     * @作者: Coke
     * @注释: 以迭代器的方式遍历数组
     * @DateTime: 2023/5/13 14:46
     */
    @Override
    public Iterator<T> iterator () {
        return new Iterator<T>() {
            int i = 0;
            
            @Override
            public boolean hasNext () {
                return i < size;
            }
            
            @Override
            public T next () {
                return (T) array[i++];
            }
        };
    }
    
    /**
     * @return Stream<T>
     * @作者: Coke
     * @注释: 使用流的方式遍历
     * @DateTime: 2023/5/13 14:56
     */
    public Stream<T> stream () {
        return (Stream<T>) Stream.of(Arrays.copyOfRange(array, 0, size));
    }
    
    /**
     * @param index:
     * @return T
     * @作者: Coke
     * @注释: 根据索引删除元素
     * @DateTime: 2023/5/13 16:38
     */
    public T remove (int index) {
        if (index >= 0 && index <= size - 1) {
            T removed = (T) array[index];
            if (index != size - 1) {
                System.arraycopy(array, index + 1, array, index, size - index - 1);
            }
            size--;
            return removed;
        }
        return null;
    }
    
    
}
